#pragma once
#include<assert.h>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

class Buffer
{
public:
    static const size_t kCheapPrepend = 8;
    static const size_t kInitialSize = 1024;
    explicit Buffer(size_t initialSize = kInitialSize)
        : buffer_(kCheapPrepend + kInitialSize), readIndex_(kCheapPrepend), writeIndex_(kCheapPrepend) {}

    size_t readableBytes() const { return writeIndex_ - readIndex_; }
    size_t writableBytes() const { return buffer_.size() - writeIndex_; }

    size_t prependableBytes() const { return readIndex_; }

    const char *peek() const { return begin() + readIndex_; }

    void retrieve(size_t len)
    {
        if (len < readableBytes())
        {
            readIndex_ += len; // 表示读的位置向前移动读取数量的位置
        }
        else
        {
            retrieveAll();
        }
    }
    void retrieveAll() // 缓冲区读完复位了
    {
        readIndex_ = writeIndex_ = kCheapPrepend;
    }
    std::string retrieveAllAsString()
    {
        return retriveAsString(readableBytes());
    } // 将onMessage上报的buffer数据转成string类型的数据

    std::string retriveAsString(size_t len)
    {
        assert(len <= readableBytes());
        std::string result(peek(), len);
        retrieve(len);
        return result;
    }
    void ensureWritableBytes(size_t len) // 确保缓冲区有足够的空间
    {
        if (writableBytes() < len)
        {
            makespace(len); // 扩容
        }
        else
        {
            size_t readable = readableBytes();
            std::copy(begin() + readIndex_, begin() + writeIndex_, begin() + kCheapPrepend);
            readIndex_ = kCheapPrepend;
            writeIndex_ = readIndex_ + readable;
        }
    }
    //将data中的数据添加到缓冲区当中
    void append(const char *data, size_t len)
    {
        ensureWritableBytes(len);
        std::copy(data, data + len, beginWrite());
        writeIndex_ += len;
    }
    char *beginWrite()
    {
        return begin() + writeIndex_;
    }
    const char *beginWrite() const
    {
        return begin() + writeIndex_;
    }
    //从fd上读取数据
    ssize_t readFd(int fd,int *saveErrno);

    ssize_t writefd(int fd,int*saveError);
private:
    char *begin() { return &*buffer_.begin(); } // 这里是区解引用数组返回的迭代器再取地址;
    const char *begin() const
    {
        return &*buffer_.begin();
    }

    void makespace(size_t len)
    {
        if (writableBytes() + prependableBytes() < len + kCheapPrepend)
        {
            buffer_.resize(writeIndex_ + len);
        }
        else
        {
        }
    }

    vector<char> buffer_;
    size_t readIndex_;
    size_t writeIndex_;
};